home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / OldSrc / CH11 / SRC / OBJPGON1.CLS < prev    next >
Text File  |  1996-05-04  |  8KB  |  303 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4. END
  5. Attribute VB_Name = "ObjPolygon"
  6. Attribute VB_Creatable = False
  7. Attribute VB_Exposed = False
  8. Option Explicit
  9.  
  10. ' Point3D is defined in module M3OPS.BAS as:
  11. '    Type Point3D
  12. '        coord(1 To 4) As Single
  13. '        trans(1 To 4) As Single
  14. '    End Type
  15.  
  16. Private NumPts As Integer ' Number of points.
  17. Private Points() As Point3D  ' Data points.
  18.  
  19. Private IsCulled As Boolean
  20.  
  21.  
  22.  
  23.  
  24.  
  25. ' ***********************************************
  26. ' Create a polyline representing the normal to
  27. ' this polygon and place it in the given objects
  28. ' collection.
  29. ' ***********************************************
  30. Sub CreateNormal(Objects As Collection)
  31. Dim pline As New ObjPolyline
  32. Dim x1 As Single
  33. Dim y1 As Single
  34. Dim z1 As Single
  35. Dim x2 As Single
  36. Dim y2 As Single
  37. Dim z2 As Single
  38.  
  39.     Objects.Add pline
  40.     UnitNormalSegment x1, y1, z1, x2, y2, z2
  41.     pline.AddSegment x1, y1, z1, x2, y2, z2
  42. End Sub
  43.  
  44.  
  45. ' ***********************************************
  46. ' Compute a normal vector for this polygon.
  47. ' ***********************************************
  48. Public Sub NormalVector(nx As Single, ny As Single, nz As Single)
  49. Dim Ax As Single
  50. Dim Ay As Single
  51. Dim Az As Single
  52. Dim Bx As Single
  53. Dim By As Single
  54. Dim Bz As Single
  55.  
  56.     Ax = Points(2).coord(1) - Points(1).coord(1)
  57.     Ay = Points(2).coord(2) - Points(1).coord(2)
  58.     Az = Points(2).coord(3) - Points(1).coord(3)
  59.     Bx = Points(3).coord(1) - Points(2).coord(1)
  60.     By = Points(3).coord(2) - Points(2).coord(2)
  61.     Bz = Points(3).coord(3) - Points(2).coord(3)
  62.     m3Cross nx, ny, nz, Ax, Ay, Az, Bx, By, Bz
  63. End Sub
  64.  
  65.  
  66.  
  67.  
  68. ' ***********************************************
  69. ' Compute the unit normal line segment for this
  70. ' polygon.
  71. ' ***********************************************
  72. Sub UnitNormalSegment(x1 As Single, y1 As Single, z1 As Single, x2 As Single, y2 As Single, z2 As Single)
  73. Dim i As Integer
  74. Dim nx As Single
  75. Dim ny As Single
  76. Dim nz As Single
  77.     
  78.     UnitNormalVector nx, ny, nz
  79.     
  80.     x1 = 0
  81.     y1 = 0
  82.     z1 = 0
  83.     For i = 1 To NumPts
  84.         x1 = x1 + Points(i).coord(1)
  85.         y1 = y1 + Points(i).coord(2)
  86.         z1 = z1 + Points(i).coord(3)
  87.     Next i
  88.     x1 = x1 / NumPts
  89.     y1 = y1 / NumPts
  90.     z1 = z1 / NumPts
  91.  
  92.     x2 = x1 + nx
  93.     y2 = y1 + ny
  94.     z2 = z1 + nz
  95. End Sub
  96.  
  97.  
  98. ' ***********************************************
  99. ' Compute the unit normal vector for this
  100. ' polygon.
  101. ' ***********************************************
  102. Sub UnitNormalVector(nx As Single, ny As Single, nz As Single)
  103. Dim D As Single
  104.  
  105.     NormalVector nx, ny, nz
  106.     D = Sqr(nx * nx + ny * ny + nz * nz)
  107.     nx = nx / D
  108.     ny = ny / D
  109.     nz = nz / D
  110. End Sub
  111.  
  112.  
  113.  
  114.  
  115.  
  116. ' ***********************************************
  117. ' Set or clear the IsCulled flag.
  118. ' ***********************************************
  119. Property Let Culled(value As Boolean)
  120.     IsCulled = value
  121. End Property
  122.  
  123.  
  124. ' ***********************************************
  125. ' Return true if the polygon has been culled.
  126. ' ***********************************************
  127. Property Get Culled() As Boolean
  128.     Culled = IsCulled
  129. End Property
  130.  
  131. ' ***********************************************
  132. ' Return a string indicating the object type.
  133. ' ***********************************************
  134. Property Get ObjectType() As String
  135.     ObjectType = "POLYGON"
  136. End Property
  137.  
  138. ' ************************************************
  139. ' Add one or more points to the polygon.
  140. ' ************************************************
  141. Public Sub AddPoint(ParamArray coord() As Variant)
  142. Dim num_pts As Integer
  143. Dim i As Integer
  144. Dim pt As Integer
  145.  
  146.     num_pts = (UBound(coord) + 1) \ 3
  147.     ReDim Preserve Points(1 To NumPts + num_pts)
  148.  
  149.     pt = 0
  150.     For i = 1 To num_pts
  151.         Points(NumPts + i).coord(1) = coord(pt)
  152.         Points(NumPts + i).coord(2) = coord(pt + 1)
  153.         Points(NumPts + i).coord(3) = coord(pt + 2)
  154.         Points(NumPts + i).coord(4) = 1#
  155.         pt = pt + 3
  156.     Next i
  157.  
  158.     NumPts = NumPts + num_pts
  159. End Sub
  160.  
  161. ' ***********************************************
  162. ' Fix the data coordinates at their transformed
  163. ' values.
  164. ' ***********************************************
  165. Public Sub FixPoints()
  166. Dim i As Integer
  167. Dim j As Integer
  168.  
  169.     For i = 1 To NumPts
  170.         For j = 1 To 3
  171.             Points(i).coord(j) = Points(i).trans(j)
  172.         Next j
  173.     Next i
  174. End Sub
  175.  
  176. ' ************************************************
  177. ' Apply a transformation matrix which may not
  178. ' contain 0, 0, 0, 1 in the last column to the
  179. ' object.
  180. ' ************************************************
  181. Public Sub ApplyFull(M() As Single)
  182. Dim i As Integer
  183.  
  184.     If IsCulled Then Exit Sub
  185.     For i = 1 To NumPts
  186.         m3ApplyFull Points(i).coord, M, Points(i).trans
  187.     Next i
  188. End Sub
  189.  
  190. ' ************************************************
  191. ' Apply a transformation matrix to the object.
  192. ' ************************************************
  193. Public Sub Apply(M() As Single)
  194. Dim i As Integer
  195.  
  196.     If IsCulled Then Exit Sub
  197.     For i = 1 To NumPts
  198.         m3Apply Points(i).coord, M, Points(i).trans
  199.     Next i
  200. End Sub
  201.  
  202.  
  203. ' ************************************************
  204. ' Apply a nonlinear transformation.
  205. ' ************************************************
  206. Public Sub Distort(D As Object)
  207. Dim i As Integer
  208.  
  209.     For i = 1 To NumPts
  210.         D.Distort Points(i).coord(1), Points(i).coord(2), Points(i).coord(3)
  211.     Next i
  212. End Sub
  213.  
  214. ' ************************************************
  215. ' Write a polyline to a file using Write.
  216. ' Begin with "POLYGON" to identify this object.
  217. ' ************************************************
  218. Public Sub FileWrite(filenum As Integer)
  219. Dim i As Integer
  220.  
  221.     Write #filenum, "POLYGON", NumPts
  222.     
  223.     ' Write the points.
  224.     For i = 1 To NumPts
  225.         Write #filenum, Points(i).coord(1), Points(i).coord(2), Points(i).coord(3)
  226.     Next i
  227. End Sub
  228.  
  229. ' ************************************************
  230. ' Draw the transformed points on a Form, Printer,
  231. ' or PictureBox.
  232. ' ************************************************
  233. Public Sub Draw(canvas As Object, Optional r As Variant)
  234. Dim pt As Integer
  235.  
  236.     ' Don't draw if culled.
  237.     If IsCulled Then Exit Sub
  238.     
  239.     On Error Resume Next
  240.     canvas.CurrentX = Points(NumPts).trans(1)
  241.     canvas.CurrentY = Points(NumPts).trans(2)
  242.     For pt = 1 To NumPts
  243.         canvas.Line _
  244.             -(Points(pt).trans(1), Points(pt).trans(2))
  245.     Next pt
  246. End Sub
  247. ' ***********************************************
  248. ' Cull if any points are behind the center of
  249. ' projection.
  250. ' ***********************************************
  251. Public Sub ClipEye(r As Single)
  252. Dim pt As Integer
  253.  
  254.     If IsCulled Then Exit Sub
  255.     For pt = 1 To NumPts
  256.         If Points(pt).trans(3) >= r Then Exit For
  257.     Next pt
  258.     If pt <= NumPts Then IsCulled = True
  259. End Sub
  260. ' ***********************************************
  261. ' Perform backface removal.
  262. ' ***********************************************
  263. Public Sub Cull(X As Single, Y As Single, z As Single)
  264. Dim Ax As Single
  265. Dim Ay As Single
  266. Dim Az As Single
  267. Dim nx As Single
  268. Dim ny As Single
  269. Dim nz As Single
  270.  
  271.     ' Compute a normal to the face.
  272.     NormalVector nx, ny, nz
  273.  
  274.     ' Compute a vector from the center of
  275.     ' projection to the face.
  276.     Ax = Points(1).coord(1) - X
  277.     Ay = Points(1).coord(2) - Y
  278.     Az = Points(1).coord(3) - z
  279.     
  280.     ' See if the vectors meet at an angle < 90.
  281.     IsCulled = (Ax * nx + Ay * ny + Az * nz > -0.0001)
  282. End Sub
  283.  
  284. ' ************************************************
  285. ' Read a polyline from a file using Input.
  286. ' Assume the "POLYGON" label has already been
  287. ' read.
  288. ' ************************************************
  289. Public Sub FileInput(filenum As Integer)
  290. Dim i As Integer
  291.  
  292.     Input #filenum, NumPts
  293.     
  294.     ' Allocate and read the points.
  295.     ReDim Points(1 To NumPts)
  296.     For i = 1 To NumPts
  297.         Input #filenum, Points(i).coord(1), Points(i).coord(2), Points(i).coord(3)
  298.         Points(i).coord(4) = 1#
  299.     Next i
  300. End Sub
  301.  
  302.  
  303.